package com.gugee.ins.data.common.util;

import io.protostuff.LinkedBuffer;
import io.protostuff.ProtostuffIOUtil;
import io.protostuff.Schema;
import io.protostuff.runtime.RuntimeSchema;

/**
 * 序列化工具
 *
 * @author luolifeng
 * @version 1.0.0
 * Date 2020/10/04
 * Time 15:53
 */
public class ProtostuffUtil {

    private static final ThreadLocal<LinkedBuffer> BUFFERS = new ThreadLocal<>();

    /**
     * 私有构造器
     */
    private ProtostuffUtil(){

    }

    /**
     * 序列化
     *
     * @param message 序列化数据
     * @param tClass  .class
     * @param <T>     类型
     * @return byte[]
     */
    public static <T> byte[] serializer(T message, Class<T> tClass) {
        LinkedBuffer linkedBuffer = BUFFERS.get();
        /**
         * 存储buffer到线程局部变量中，避免每次序列化操作都分配内存提高序列化性能
         */
        if (linkedBuffer == null) {
            linkedBuffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);
            BUFFERS.set(linkedBuffer);
        }
        try {
                Schema<T> schema = RuntimeSchema.getSchema(tClass);
                return ProtostuffIOUtil.toByteArray(message, schema, linkedBuffer);
            } finally {
                linkedBuffer.clear();
        }
    }

    /**
     * 反序列化
     *
     * @param bytes  bytes
     * @param tClass .class
     * @param <T>    类型
     * @return T
     */
    public static <T> T deserializer(byte[] bytes, Class<T> tClass) {
        /**
         *
         */
        Schema<T> schema = RuntimeSchema.getSchema(tClass);
        T message = schema.newMessage();
        ProtostuffIOUtil.mergeFrom(bytes, message, schema);
        return message;
    }

    /**
     * 清除
     */
    public static void unload() {
        BUFFERS.remove();
    }
}